package com.sunxiansheng.threadpool.config;

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Description: 自定义的线程工厂
 * @Author sun
 * @Create 2024/7/24 16:32
 * @Version 1.0
 */
public class CustomNameThreadFactory implements ThreadFactory {
    /**
     * 线程池计数器（当创建一个新的线程工厂实例时，该计数器递增，区分不同的线程池）
     */
    private static final AtomicInteger poolNumber = new AtomicInteger(1);
    /**
     * 线程计数器（用于记录由该线程工厂创建的线程数量，每创建一个新线程，该计数器递增）
     */
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    /**
     * 线程组（线程所属的线程组，通常用于管理线程的集合）
     */
    private final ThreadGroup threadGroup;
    /**
     * 线程名字前缀（用于标识线程池和线程编号的前缀）
     */
    private final String namePrefix;

    /**
     * 构造函数：每次创建一个新的线程工厂实例时，确定该工厂所生成线程的名字前缀
     *
     * @param threadName 自定义线程名称前缀，相当于线程池的名称
     */
    public CustomNameThreadFactory(String threadName) {
        // 获取当前的安全管理器，以确定线程组
        SecurityManager securityManager = System.getSecurityManager();
        threadGroup =
                (securityManager != null)
                        ? securityManager.getThreadGroup()
                        : Thread.currentThread().getThreadGroup();

        // 如果没有设置线程名称，赋予默认值"pool"
        if (threadName == null || "".equals(threadName.trim())) {
            threadName = "pool";
        }

        // 生成线程名字前缀，格式为：线程名-线程池号-thread-
        namePrefix = threadName
                + "-" + poolNumber.getAndIncrement()
                + "-thread-";
    }

    /**
     * 创建一个新的线程，并应用自定义的设置
     *
     * @param r 要在新线程中执行的 Runnable 对象
     * @return 新创建的线程对象
     */
    @Override
    public Thread newThread(Runnable r) {
        // 创建线程，指定名字格式为：线程名-线程池号-thread-线程号
        Thread thread = new Thread(threadGroup, r, namePrefix + threadNumber.getAndIncrement());

        // ============================== 自定义的对创建的线程操作的逻辑 ==============================
        // 检查是否为守护线程
        if (thread.isDaemon()) {
            // 如果是守护线程，则设置为非守护线程
            thread.setDaemon(false);
        }
        // 判断线程的优先级是否为默认优先级5
        if (thread.getPriority() != Thread.NORM_PRIORITY) {
            // 如果不是，则将该线程设置为默认优先级
            thread.setPriority(Thread.NORM_PRIORITY);
        }
        // ============================== 自定义的对创建的线程操作的逻辑 ==============================

        return thread;
    }
}